#pragma once
#include "stdafx.h"
#include "FileInputBuffer.h"
#include <map>

/**
* This class is to read the quality scores from .prb file and get the Kmer from it.
* I provide a space for
* It provide the function to do Tade's DP to estimate the right tail of histogram.
*/
class CPWM
{
public:
    CPWM(void);
    CPWM(unsigned int iKmerLength);
    ~CPWM(void);

    // Read in the quality score for each Kmer from a file. To reuse space, this can be done many time.
    bool readinQaulityScore(ifstream &ifile);
    // Overriding, instead of input from a file, input from a buffer to to batch I/O
    bool readinQaulityScore(FileInputBuffer* inputBuffer);

    // Get the most likely sequence base to the pass in buffer and return its sum of score.
    int  getSequence(char* caSeq);
    // A function use for test set up: Given a kmer set the correspondent NT 40 and other -40
    void  setPWM(char* kmer); //Set qualtiy score in PWM for testing, according to kmer
    void  setPWM(int iPosi, double qA, double qC, double qG, double qT); //According to position
    // return the quality score on posId in 0:K-1 and ntId { a=0, c=1, g=2, t=3 }
    int   getBestScoreSum(void);
    int   getScoreSum(char* mappedRef);
    //Return the quality score of the base on the given position.
    char  getQScore(char nt, unsigned int posId);
    //Same as getQScore, but use ntId as ptr directly
    char  getScore(unsigned int ntId, unsigned int posId);
    //The Qscore is encoded using a char with range -40 to 40
    static double convertQScore2Prob(char score);
    //The Qscore is encoded using a char with range -40 to 40
    static char   convertProb2QScore(double Prob);
    static int getQualityScore(CPWM &pwm, char* caRef);

    //Return a map of score and frequncy, which sorted by score, need to be delete in the future.
    map<int, double>* getScoresHist(void); // remember to DELETE the returned map if not used
    // From the score and distribution, a p-Value will give an alignment

    // To do one step in Tade's DP algorithm in finding the combination of sum of scores
    map<int, double>* getSumsOfScoresFrequencyInDPStep(map<int, double>* ScoreMap, int steps);

    double getSignificance(map<int, double>* hist, int score); // Get the # of pathes has better score
    double getPValue(map<int, double>* hist, int score); // Get pValue by getSignificance()/# of pathes

    unsigned int iKmerLength;
    static const unsigned int NUM_NT = 4; // 4 kinds of nucelotide
    static const char* NT; // use to convert 0, 1, 2, 3 to a, c, g, t;
    static const int SCORE_UPPERBOUND = 40; // The range of quality score in the file
    static const int SCORE_LOWERBOUND = -40;
    static const unsigned int SIZE_OF_RANKED_SCORE_MAP = 1000; // The size of the ranked score to save computing time
    static unsigned int NTMap(char base); // covert a, c, g, t to 0, 1, 2, 3
private:
    int initialiation(unsigned int iKmerLength);
    // called by readinQaulityScore. The buffer contains the score info of each Kmer
    bool getQaulityScores(char* buffer);

    // Quality Score usually from -40 to 40, for 4 kinds of nucleotide
    char* caQualityScore[NUM_NT];
};


